package routers

import (
	"encoding/json"
	"net/http"
	"strconv"

	"gitee.com/kessil/chicory/internal/config"
	"gitee.com/kessil/chicory/internal/middleware"
	"gitee.com/kessil/chicory/internal/repositories"

	"github.com/go-chi/chi/v5"
	"xorm.io/xorm"
)

// GenericCRUDRouter 泛型CRUD路由器
type GenericCRUDRouter[T any] struct {
	db            *xorm.Engine
	cfg           *config.Config
	repo          *repositories.Repository[T]
	resource      string
	middleware    []func(http.Handler) http.Handler
	allowedFields []string
}

// NewGenericCRUDRouter 创建新的泛型CRUD路由器
func NewGenericCRUDRouter[T any](db *xorm.Engine, cfg *config.Config, resource string, allowedFields []string) *GenericCRUDRouter[T] {
	return &GenericCRUDRouter[T]{
		db:            db,
		cfg:           cfg,
		repo:          repositories.NewRepository[T](db),
		resource:      resource,
		allowedFields: allowedFields,
	}
}

// WithMiddleware 添加中间件
func (g *GenericCRUDRouter[T]) WithMiddleware(middleware ...func(http.Handler) http.Handler) *GenericCRUDRouter[T] {
	g.middleware = append(g.middleware, middleware...)
	return g
}

// Routes 返回路由
func (g *GenericCRUDRouter[T]) Routes() chi.Router {
	r := chi.NewRouter()

	// 应用所有中间件
	for _, mw := range g.middleware {
		r.Use(mw)
	}

	// 应用分页中间件
	r.Use(middleware.PaginationMiddleware(g.cfg))

	// 应用查询中间件（使用允许的字段）
	r.Use(middleware.QueryMiddleware(g.allowedFields))

	// 应用默认中间件
	r.Use(middleware.JSONResponseMiddleware)

	// CRUD路由
	r.Get("/", g.list)
	r.Post("/", g.create)
	r.Get("/{id}", g.get)
	r.Put("/{id}", g.update)
	r.Patch("/{id}", g.patch)
	r.Delete("/{id}", g.delete)

	return r
}

// // all 列表查询（使用中间件处理的筛选）
// func (g *GenericCRUDRouter[T]) all(w http.ResponseWriter, r *http.Request) {
// 	// 从中间件获取筛选条件
// 	filters := middleware.GetQueryFiltersFromContext(r)

// 	// 执行查询
// 	var items []T
// 	// var total int64
// 	var err error

// 	if len(filters) > 0 {
// 		// 使用带筛选的查询
// 		items, err = g.repo.GetAllWithFilters(filters)
// 	} else {
// 		// 使用普通查询
// 		items, _, err = g.repo.GetAll(nil)
// 	}

// 	if err != nil {
// 		middleware.JSONError(w, http.StatusInternalServerError, "Failed to get "+g.resource)
// 		return
// 	}

// 	middleware.JSONSuccess(w, items)
// }

// list 列表查询（使用中间件处理的分页和筛选）
func (g *GenericCRUDRouter[T]) list(w http.ResponseWriter, r *http.Request) {
	// 从中间件获取分页信息
	page, pageSize := middleware.GetPaginationFromContext(r)

	// 从中间件获取筛选条件
	filters := middleware.GetQueryFiltersFromContext(r)

	// 执行查询
	var items []T
	var total int64
	var err error

	if len(filters) > 0 {
		// 使用带筛选的查询
		items, total, err = g.repo.GetManyWithFilters(filters, page, pageSize)
	} else {
		// 使用普通查询
		items, total, err = g.repo.GetMany(nil, page, pageSize)
	}

	if err != nil {
		middleware.JSONError(w, http.StatusInternalServerError, "Failed to get "+g.resource)
		return
	}

	// 构建响应
	responseData := map[string]interface{}{
		"pageData": items,
		"total":    total,
		"pageNo":   page,
		"pageSize": pageSize,
	}

	if len(filters) > 0 {
		responseData["filters"] = filters
	}

	if g.cfg.Server.IncludeOriginUrl {
		responseData["originUrl"] = r.URL.String()
	}

	middleware.JSONSuccess(w, responseData)
}

// get 根据ID查询
func (g *GenericCRUDRouter[T]) get(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
	if err != nil {
		middleware.JSONError(w, http.StatusBadRequest, "Invalid ID")
		return
	}

	item, err := g.repo.GetByID(id)
	if err != nil {
		middleware.JSONError(w, http.StatusInternalServerError, "Failed to get "+g.resource)
		return
	}

	if item == nil {
		middleware.JSONError(w, http.StatusNotFound, g.resource+" not found")
		return
	}

	middleware.JSONSuccess(w, item)
}

// create 创建
func (g *GenericCRUDRouter[T]) create(w http.ResponseWriter, r *http.Request) {
	var item T
	if err := json.NewDecoder(r.Body).Decode(&item); err != nil {
		middleware.JSONError(w, http.StatusBadRequest, "Invalid request")
		return
	}

	if err := g.repo.Create(&item); err != nil {
		middleware.JSONError(w, http.StatusInternalServerError, "Failed to create "+g.resource)
		return
	}

	middleware.JSONSuccess(w, item)
}

// update 更新
func (g *GenericCRUDRouter[T]) update(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
	if err != nil {
		middleware.JSONError(w, http.StatusBadRequest, "Invalid ID")
		return
	}

	var item T
	if err := json.NewDecoder(r.Body).Decode(&item); err != nil {
		middleware.JSONError(w, http.StatusBadRequest, "Invalid request")
		return
	}

	if err := g.repo.Update(id, &item); err != nil {
		middleware.JSONError(w, http.StatusInternalServerError, "Failed to update "+g.resource)
		return
	}

	// 获取更新后的数据
	updated, err := g.repo.GetByID(id)
	if err != nil {
		middleware.JSONError(w, http.StatusInternalServerError, "Failed to get updated "+g.resource)
		return
	}

	middleware.JSONSuccess(w, updated)
}

// patch 部分更新
func (g *GenericCRUDRouter[T]) patch(w http.ResponseWriter, r *http.Request) {
	// 简单的Patch实现
	g.update(w, r) // 暂时使用完整的update，后续可以优化
}

// delete 删除
func (g *GenericCRUDRouter[T]) delete(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
	if err != nil {
		middleware.JSONError(w, http.StatusBadRequest, "Invalid ID")
		return
	}

	if err := g.repo.Delete(id); err != nil {
		middleware.JSONError(w, http.StatusInternalServerError, "Failed to delete "+g.resource)
		return
	}

	middleware.JSONSuccess(w, nil)
}
